package com.chengyu.stock.alg;

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.ShardingValue;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.joda.time.DateTime;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

//定义公共的分库算法类：包含精准和范围查询数据
public class CommonAlg4Db implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {
    //精准查询，eg:select * from stock_block_rt_info where cur_time='2022-12-03 09:40:00'  (in =)
    @Override
    public String doSharding(Collection<String> dsNames, PreciseShardingValue<Date> shardingValue) {
        //获取逻辑表
        String logicTableName = shardingValue.getLogicTableName();
        //获取分片字段名称
        String columnName = shardingValue.getColumnName();
        //获取精准查询的条件值
        Date curTime = shardingValue.getValue();
        //根据查询的日期时间中的年份获取对应的数据源
        String curYear = new DateTime(curTime).getYear() +"";
        String ds = dsNames.stream().filter(dsName -> dsName.endsWith(curYear)).findFirst().get();
        return ds;
    }
    //范围查询时使用该方法 eg:select * from stock_block_rt_info where cur_time  between '2021-06-03 09:40:00'  and '2022-12-03 09:40:00'
    @Override
    public Collection<String> doSharding(Collection<String> dsNames, RangeShardingValue<Date> shardingValue) {
        //获取范围封装对象
        Range<Date> valueRange = shardingValue.getValueRange();
        //判断上限和下限
        //上限
        if(valueRange.hasUpperBound()){
            //获取上限值
            int maxYear = new DateTime(valueRange.upperEndpoint()).getYear();
            //过滤数据源中后缀小于等于上限值的数据源集合
            dsNames=dsNames.stream().filter(dsName->Integer.valueOf(dsName.substring(dsName.lastIndexOf("-")+1))<=maxYear).collect(Collectors.toList());
        }
        //下限
        if(valueRange.hasLowerBound()){
            //获取下限值
            int minYear = new DateTime(valueRange.lowerEndpoint()).getYear();
            //过滤数据源中后缀小于等于上限值的数据源集合
            dsNames=dsNames.stream().filter(dsName->Integer.valueOf(dsName.substring(dsName.lastIndexOf("-")+1))>=minYear).collect(Collectors.toList());
        }
        return dsNames;
    }
}
